home *** CD-ROM | disk | FTP | other *** search
/ Aminet 6 / Aminet 6 - June 1995.iso / Aminet / dev / misc / gadoc.lha / GAdoc.c / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-28  |  23.9 KB  |  905 lines

  1.  
  2. /****h* gadoc.c/TheNameOfTheGame ***
  3. *
  4. *  NAME
  5. *    gadoc
  6. *
  7. *  COPYRIGHT
  8. *    Gerhard Leibrock
  9. *    This software is subject to the ``Standard Amiga FD-Software Copyright Note''
  10. *    It is Cardware as defined in paragraph 4.c.
  11. *    If you like it and use it regularly please send a postcard to the
  12. *    author. For more information please read ``AFD-COPYRIGHT''
  13. *    (Version 1 or higher).
  14. *
  15. *  FUNCTION
  16. *    This program will be of great use for any programmer, since it
  17. *    makes it possible to extract the so called autodocs from source
  18. *    codes and generates a texinfo file out of them.
  19. *    (The autodoc format is explained in detail in the manual.)
  20. *
  21. *  AUTHOR
  22. *    Gerhard Leibrock
  23. *    Neuhäuselerstr. 12       InterNET:
  24. *    66459 Kirkel                      leibrock@@fsinfo.cs.uni-sb.de
  25. *    T.: 06849/6134                    fach5@@cipsol.cs.uni-sb.de   
  26. *    Germany
  27. *
  28. *  VERSION
  29. *    1.2 (27-March-1995)
  30. *
  31. *  NOTES
  32. *    Started 10-Feb-1995
  33. *    Read the english manual.
  34. *
  35. ***/
  36.  
  37. /* Deutscher Header // German Header */
  38.  
  39. /*DE*h* gadoc.c/UmWasGehtsHier ***
  40. *
  41. *  NAME
  42. *    gadoc
  43. *
  44. *  COPYRIGHT
  45. *    Gerhard Leibrock
  46. *    Diese Software unterliegt der "Standard Amiga FD-Software Copyright Note"
  47. *    Sie ist Cardware, wie definiert in Absatz 4c. Falls du sie magst und
  48. *    regelmäßig benutzt, sende bitte eine Postkarte an den Autor. Für mehr
  49. *    Informationen lies bitte "AFD-COPYRIGHT" (Version 1 oder höher).
  50. *
  51. *  FUNCTION
  52. *    Dieses Programm ist eine riesige Hilfe für alle Programmierer, die mit
  53. *    der Dokumentation zu Ihren Produkten auf dem Kriegsfuß stehen.
  54. *    GAdoc unterstützt Autdocs (Siehe englisches Handbuch), die direkt in
  55. *    den Quellcode eingefügt werden. Somit haben Sie doppelten Nutzen:
  56. *    Sie können diese Dokumentation während Ihrer Arbeit am Bildschirm
  57. *    lesen und verändern oder Sie mittels gadoc in eine texinfo Datei
  58. *    umwandeln und dann weiterverarbeiten.
  59. *
  60. *  AUTHOR
  61. *    Gerhard Leibrock
  62. *    Neuhäuselerstr. 12       InterNET:
  63. *    66459 Kirkel                      leibrock@@fsinfo.cs.uni-sb.de
  64. *    T.: 06849/6134                    fach5@@cipsol.cs.uni-sb.de   
  65. *    Deutschland
  66. *
  67. *  VERSION
  68. *    1.2 (27-März-1995)
  69. *
  70. *  NOTES
  71. *    Angefangen 10-Feb-1995
  72. *    Lesen Sie unbedingt das (englische) Handbuch.
  73. *
  74. ***/
  75.  
  76. char *VER = "$VER: GAdoc 1.2 (c) Gerhard Leibrock (27.03.95)";
  77.  
  78.  
  79. #include <stdio.h>
  80. #include <string.h>
  81. #include <stdlib.h>
  82. #include <time.h>
  83.  
  84. /* Include the information for creating an amiga icon */
  85. #include "IconData.h"
  86.  
  87. typedef enum{FALSE, TRUE} BOOL;
  88.  
  89.  
  90. /****i* gadoc.c/WriteTexinfo() ********
  91. *
  92. *  NAME
  93. *    WriteTexinfo -- Write the header of the generated output file
  94. *
  95. *  SYNOPSIS
  96. *    WriteTexinfo(fptr, filename, author, project, version, copyright,
  97. *                  amiga_support)
  98. *
  99. *    void WriteTexinfo
  100. *       (FILE *fptr, char *filename, char *author,
  101. *       char *project, char *version, char *copyright, BOOL amiga_support)
  102. *
  103. *  FUNCTION
  104. *    This function writes the header for the .menu file, in which the
  105. *    titlepage gets specified and some layout flags like dina4 paper.
  106. *
  107. *  INPUTS
  108. *    fptr          - Pointer to the output file
  109. *    filename      - name of the hypertext file, that could be generated
  110. *    author        - Name ot the programs author (specified in *h* section)
  111. *    project       - Name of the project this file belongs to
  112. *    version       - Version
  113. *    copyright     - Who holds the copyright?
  114. *    amiga_support - Include the line \\input amigatexinfo?
  115. *
  116. *  RESULT
  117. *    None
  118. *
  119. *  EXAMPLE
  120. *    FILE *out;
  121. *    char *filename, author, project, version, copyright;
  122. *    BOOL amiga_support;
  123. *
  124. *    ...
  125. *
  126. *    WriteTexinfo(fptr, filename, author, project, version, copyright,
  127. *                  amiga_support);
  128. *
  129. *  NOTES
  130. *
  131. *  BUGS
  132. *    None
  133. *
  134. *  SEE ALSO
  135. *    
  136. ***/
  137.  
  138. void WriteTexinfo
  139.     (FILE *fptr, char *filename, char *author,
  140.      char *project, char *version, char *copyright, BOOL amiga_support)
  141. {
  142.   /* To obtain the system-time -> Included as the date of extraction */
  143.   time_t t;
  144.  
  145.   /* To eliminate path-symbols like `:' or `/'; */
  146.   int i;
  147.  
  148.   time(&t);
  149.  
  150.  
  151.   for(i=strlen(filename)-1; i>=0; i--)
  152.     if(filename[i] == ':' || filename[i]=='/') break;
  153.  
  154.   if(amiga_support) fputs("\\input amigatexinfo\n", fptr);
  155.   fputs("\\input texinfo @c -*-Texinfo-*-\n\n",    fptr);
  156.   fprintf(fptr,
  157.     "@setfilename %s.guide\n"
  158.     "@settitle Autodocs for %s\n"
  159.     "@finalout\n@setchapternewpage on\n\n"
  160.     "@titlepage\n@title Autodocs for %s\n"
  161.     "@subtitle Documentation taken from source code\n"
  162.     "@subtitle\n"
  163.     "@subtitle Version %s\n"
  164.     "@subtitle\n"
  165.     "@subtitle Printed version\n"
  166.     "@subtitle\n"
  167.     "@subtitle Extracted %s\n"
  168.     "@subtitle \n"
  169.     "@author %s\n\n"
  170.     "@page\n@vskip 0pt plus 1filll\n"
  171.     "Copyright @copyright{} by %s\n"
  172.     "@end titlepage\n\n"
  173.     "@ifinfo\n@node Top\n@top\n@unnumbered\n\n"
  174.     "@center Autodocs for %s\n"
  175.     "Written by %s\n"
  176.     "@copyright{} Copyright by %s\n"
  177.     "Documentation taken directly from source code\n\n"
  178.     "Extracted %s\n\n"
  179. #if 0
  180.     "Docs generated using GAdoc, (c) by Gerhard Leibrock, Feb 1995\n\n"
  181. #endif
  182.     "@end ifinfo\n\n\n"
  183.     "@menu\n",
  184.     &filename[i+1], project, project, version,
  185.     ctime(&t),  author, copyright,
  186.     project, author, copyright, ctime(&t));
  187. }
  188.  
  189.  
  190. /****i* gadoc.c/OpenOutputFiles() ********
  191. *
  192. *  NAME
  193. *    OpenOutputFiles -- Open the needed output files
  194. *
  195. *  SYNOPSIS
  196. *    OpenOutputFiles(fname, menu, data)
  197. *
  198. *    void OpenOutputFiles(char *fname, FILE **menu, FILE **data)
  199. *
  200. *  FUNCTION
  201. *    Open two files named <fname>.data and <fname>.menu. These two files
  202. *    are needed for the generated texinfo output. <fname>.menu is the
  203. *    main part, which includes <fname>.data.
  204. *
  205. *  INPUTS
  206. *   fname - Main part of the name for the file to open
  207. *   menu  - Adress of file pointer for <fname>.menu.
  208. *   data  - Adress of file pointer for <fname>.data.
  209. *
  210. *  RESULT
  211. *    None
  212. *
  213. *  EXAMPLE
  214. *    FILE *menu, *data;
  215. *    char *fname = "myfile";
  216. *
  217. *    ...
  218. *
  219. *    OpenOutputFiles(fname, &menu, &data);
  220. *
  221. *  NOTES
  222. *    MUST be called before WriteTexinfo().
  223. *
  224. *  BUGS
  225. *    None
  226. *
  227. *  SEE ALSO
  228. *    
  229. ***/
  230. void OpenOutputFiles(char *fname, FILE **menu, FILE **data)
  231. {
  232.   char buf[80];
  233.   /* Open the output file, which contains the document description and
  234.      toc */
  235.   strcpy(buf, fname); strcat(buf, ".menu");
  236.   if(!(*menu=fopen(buf, "w")))
  237.   {
  238.     printf("Could not open file %s.\n", buf);
  239.     exit(0);
  240.   }
  241.  
  242.   /* Open the file, which will contain the function descriptions,
  243.      ``fname'' will be used later agin and contains the filename */
  244.   strcpy(buf, fname); strcat(buf, ".data");
  245.   if(!(*data=fopen(buf, "w")))
  246.   {
  247.     printf("Could not open file %s!\n", buf);
  248.     exit(0);
  249.   }
  250. }
  251.  
  252.  
  253. int main(int argc, char *argv[])
  254. {
  255.   FILE *ein;
  256.   FILE *aus_menue, *aus_daten;
  257.  
  258.   int i, j;
  259.  
  260.   #define MAX_LINE_LENGTH 80
  261.   char zk[MAX_LINE_LENGTH], zk1[MAX_LINE_LENGTH], zk2[MAX_LINE_LENGTH];
  262.  
  263.   /* Name des Programmautors */
  264.   char author[50];
  265.   /* Wie heisst dass Projekt? */
  266.   char project[50];
  267.   /* Welche Version hat es? */
  268.   char version[50];
  269.   /* Wer hat das Copyright? */
  270.   char copyright[50];
  271.  
  272.   unsigned int zeile = NULL;
  273.  
  274.   BOOL autodoc_mode=FALSE;
  275.  
  276.   /* Schluesselworte fuer Auto-DOCS */
  277.   char *keywords[] = {"NAME", "SYNOPSIS", "FUNCTION", "INPUTS", "RESULT",
  278.   "EXAMPLE", "NOTES", "BUGS"};
  279.   BOOL autodoc = FALSE;
  280.   BOOL first_key = FALSE;
  281.   BOOL see_also = FALSE;    /* Im @ref{} Modus */
  282.   BOOL see_also_found = FALSE;    /* SEE ALSO schon vorgekommen */
  283.   BOOL key_found = FALSE;
  284.   BOOL key[sizeof(keywords) / sizeof(char**)];
  285.  
  286.   /* Programminteren Schluesselwoerter */
  287.   char *internal_keywords[] = {"NAME", "COPYRIGHT", "FUNCTION", "AUTHOR",
  288.   "NOTES", "VERSION"};
  289.   BOOL internal_key[sizeof(internal_keywords) / sizeof(char**)];
  290.   BOOL internal = FALSE; /* Internal schon mal aufgerufen? */
  291.   BOOL internal_mode = FALSE;
  292.   /* Zum Aussteigen beim Einlesen der Datei bei Endkennung */
  293.   BOOL internal_ende = FALSE;
  294.  
  295.   /* */
  296.   BOOL first_internal = FALSE;
  297.   /* Zuletzt aktives Schluesselwort */
  298.   int last_key = -1;
  299.  
  300.   /* Extrahieren der als intern deklarierten Docs? */
  301.   BOOL extract_internal = FALSE;
  302.   /* Include amiga support? */
  303.   BOOL amiga_support = FALSE;
  304.  
  305.   /* Extract only docs with specific ID */
  306.   BOOL extract_flag = FALSE;
  307.  
  308.   char *token; /* Zum Aufsplitten der Eingabe-Datei */
  309.  
  310.   /* Flag for the -c option */
  311.   BOOL convert_comment = FALSE;
  312.  
  313.   /* Flag for the -aicon option */
  314.   BOOL amiga_icon = FALSE;
  315.  
  316.  
  317.   /* Strings, which signal the beginning of an autodoc entry */     
  318.   char generic_marker[]  = "****** ";
  319.   char internal_marker[] = "****i* ";
  320.   char author_marker[]   = "****h* ";
  321.   /* Length of the strings: IMPORTANT for checking */
  322.   #define MARKER_LENGTH 7
  323.  
  324.   /* String, that signals the end of the autodoc entry (First char gets
  325.      NOT ignored) */
  326.   char autodoc_end_marker[] = "***";
  327.   /* String length of the end marker */
  328.   #define END_LENGTH 3
  329.  
  330.   if(argc<3 || argc>8)
  331.   {
  332.     puts("This prgram extracts the AutoDOCs from your source-files\n"
  333.          "and produces two TeXinfo-files out of it:\n"
  334.          "<texinfo_file>.menu AND <texinfo_file>.data\n"
  335.          "The *.menu file is the main part, use it with makeinfo.");
  336.     printf("Syntax:\n"
  337.            "\t%s <source> <texinfo_file> [-i] [-c] [-s<id>] [-amiga] [-aicon]\n"
  338.            "\t -i:     Also extract internal documentation\n"
  339.            "\t -c:     Convert \\* to /* and *\\ to */\n"
  340.            "\t -s<id>  Only extract docs with <id> ID\n"
  341.            "\t -amiga: Include amiga support for texinfo\n"
  342.            "\t -aicon: Create an Amiga icon that can be used for the guide file\n"
  343.            "(c) Gerhard Leibrock, 1995\n", argv[0]);
  344.     printf("Warning: Lines are limited to %ld chars!\n", sizeof(zk));
  345.     exit(0);
  346.   }
  347.  
  348.   /* Testen, ob der Benutzer AUCH die als INTERN deklarierten Autodocs
  349.      erhalten moechte */
  350.   if(argc>=4)
  351.     for(i=3; i<argc; i++)
  352.     {
  353.       if(!strcmp(argv[i], "-i"))
  354.       {
  355.         if(extract_internal)
  356.         {
  357.       printf("%s: Specified twice (See argument #%d)\n", argv[i], i+1);
  358.       exit(0);
  359.         }
  360.         else
  361.           extract_internal = TRUE;
  362.       }
  363.       else if(!strcmp(argv[i], "-amiga"))
  364.       {
  365.         if(amiga_support)
  366.         {
  367.       printf("%s: Specified twice (See argument #%d)\n", argv[i], i+1);
  368.       exit(0);
  369.         }
  370.         else
  371.           amiga_support = TRUE;
  372.       }
  373.       else if(!strcmp(argv[i], "-aicon"))
  374.       {
  375.         if(amiga_icon)
  376.         {
  377.       printf("%s: Specified twice (See argument #%d)\n", argv[i], i+1);
  378.       exit(0);
  379.         }
  380.         else
  381.           amiga_icon = TRUE;
  382.       }
  383.       else if(!strcmp(argv[i], "-c"))
  384.       {
  385.         if(convert_comment)
  386.         {
  387.       printf("%s: Specified twice (See argument #%d)\n", argv[i], i+1);
  388.       exit(0);
  389.         }
  390.         else
  391.           convert_comment = TRUE;
  392.       }
  393.       else if(!strncmp(argv[i], "-s", 2))
  394.       {
  395.         if(extract_flag)
  396.         {
  397.       printf("%s: Specified twice (See argument #%d)\n", argv[i], i+1);
  398.       exit(0);
  399.         }
  400.         else
  401.         {
  402.           if(strlen(&(argv[i][2])) != 2)
  403.           {
  404.             printf("-s: \"%s\" is invalid, I need exactly 2 chars.\n",
  405.                    &(argv[i][2]));
  406.             exit(0);
  407.           }
  408.           /* Now adjust the tokens, that signal the beginning of an autodoc */
  409.       generic_marker[1] = internal_marker[1] =
  410.                 author_marker[1] = argv[i][2];
  411.       generic_marker[2] = internal_marker[2] =
  412.                 author_marker[2] = argv[i][3];
  413.           extract_flag = TRUE;
  414.         }
  415.       }
  416.       else
  417.       {
  418.         printf("Unknown argument: %s\n", argv[i]);
  419.         exit(0);
  420.       }
  421.     } /* Schleife ueber die Argumente beim Aufruf */
  422.  
  423.    if(amiga_icon)
  424.    {
  425.      strcpy(zk, argv[2]);
  426.      strcat(zk, ".guide.info");
  427.      printf("Writing AmigaDOS icon data \"%s\"\n", zk);
  428.      ein = fopen(zk, "wb");
  429.      if(!ein)
  430.      {
  431.        printf("Error: Could not open \"%s\" for writing.\n", zk);
  432.        exit(0);
  433.      }
  434.      fwrite(data, sizeof(data), 1, ein);
  435.      fclose(ein);
  436.    }
  437.  
  438.  
  439.   /* Open the source-file */
  440.   if(!(ein=fopen(argv[1], "r")))
  441.   {
  442.     printf("Could not open file ``%s''.\n", argv[1]);
  443.     exit(0);
  444.   }
  445.  
  446.   printf("Extracting autodocs from file \"%s\" to \"%s.menu\" and \"%s.data\".\n",
  447.       argv[1], argv[2], argv[2]);
  448.  
  449.   for(i=0; i<sizeof(keywords) / sizeof(char**); i++) key[i]=FALSE;
  450.   for(i=0; i<sizeof(internal_keywords) / sizeof(char**); i++)
  451.     internal_key[i]=FALSE;
  452.  
  453.  
  454.   /* Vorbelegen der Variablen */
  455.   strncpy(author, "Unknown", 50);
  456.   strncpy(project, argv[1], 50);
  457.   strcpy(version, "0.0");
  458.  
  459.  
  460.   while ( fgets(zk, sizeof(zk), ein) )
  461.   {
  462.     zeile++;
  463.  
  464.     /* Wir sind im Autodoc-Modus */
  465.     if(autodoc_mode)
  466.     {
  467.       if( !strncmp(zk, autodoc_end_marker, END_LENGTH) )
  468.       {/* Endkennung erreicht */
  469.     /* Testen, ob es Schluesselwoerter gibt, zu denen nichts
  470.        geschrieben wurde und zuruecksetzen */
  471.     for(i=0; i<sizeof(keywords) / sizeof(char**); i++)
  472.     {
  473.       if(!key[i]) fprintf(aus_daten, "\n@code{%s}\n", keywords[i]);
  474.       key[i]=FALSE;
  475.     }
  476.  
  477.     /* SEE ALSO schon aufgetaucht? */
  478.     if(!see_also_found) fputs("\n@code{SEE ALSO}\n", aus_daten);
  479.  
  480.     key_found = FALSE;
  481.     first_key=FALSE;
  482.     autodoc_mode = FALSE;
  483.     if(!see_also) fputs("@end example\n", aus_daten);
  484.     see_also = FALSE; see_also_found = FALSE;
  485.     fputs("\n\n\n", aus_daten);
  486.     /* Testen, ob es Schluesselwoerter gibt, zu denen nichts
  487.        geschrieben wurde. */
  488.      }
  489.       else /* Teste, auf Anfang fuer Autodoc-Modus */
  490.       {
  491.         key_found = FALSE;
  492.     /* Keine Endkennung, vielleicht aber ein neues Schlüsselwort? */
  493.  
  494.     /* Ueberlese erstes Zeichen und alle TABs, Leerzeichen */
  495.     strcpy(zk1, zk);
  496.     token = strtok(&zk[1], " \t\n");
  497.  
  498.         if(token)
  499.         {
  500.       if(!strcmp(token, "SEE"))
  501.       {
  502.         token = strtok(NULL," \t\n");
  503.         if(!strcmp(token, "ALSO"))
  504.         {
  505.           if(see_also_found)
  506.           {
  507.         printf( "Error Line %u: Either keyword SEE ALSO used twice"
  508.             "or in wrong order.\n", zeile);
  509.         exit(0);
  510.           }
  511.           /* Nun setzen wir alle Kennungen fuer Schluesselwoerter auf
  512.              gefunden, falls diese noch nicht gefunden worden sind, da
  513.              SEE ALSO das letzte zu akzeptierende Schluesselwort ist.
  514.          Ausserdem schreiben wir die Schluesselworte, da alle
  515.          vorkommen sollen */
  516.           for(i=0; i<sizeof(keywords) / sizeof(char**); i++)
  517.           {
  518.         if(!key[i]) fprintf(aus_daten, "\n@code{%s}\n", keywords[i]);
  519.         key[i]=TRUE;
  520.           }
  521.  
  522.           /* Schluesselwort "SEE ALSO" */
  523.           if(first_key) fputs("@end example\n", aus_daten);
  524.           first_key=TRUE;
  525.           key_found=TRUE;
  526.           see_also = TRUE; see_also_found = TRUE;
  527.           strcpy(zk1, "SEE ALSO");
  528.         }
  529.       }
  530.       else {
  531.         for(i=0; i< sizeof(keywords) / sizeof(char**); i++)
  532.         {
  533.           if(!strcmp(token, keywords[i]))
  534.           {
  535.             if(key[i] == TRUE)
  536.             {
  537.           printf("Error Line %u: Either keyword %s used twice"
  538.              "               or in wrong order\n",
  539.             zeile, keywords[i]);
  540.           exit(0);
  541.             }
  542.             /* Alle Schluesselwoerter, die vor diesem in der Reihenfolge
  543.                stehen, werden als belegt gekennzeichnet */
  544.         for(j=0; j<i; j++)
  545.         {
  546.           if(!key[j]) fprintf(aus_daten, "\n@code{%s}\n", keywords[j]);
  547.           key[j]=TRUE;
  548.         }
  549.         key[i]=TRUE;
  550.             if(first_key) fputs("@end example\n", aus_daten);
  551.             first_key=TRUE;
  552.             key_found=TRUE;
  553.             see_also = FALSE;
  554.             strcpy(zk1, keywords[i]);
  555.             break;
  556.           }
  557.         } /* Suche nach Keyword */
  558.       } /* ELSE */
  559.     }
  560.     if(!key_found) {
  561.       if(see_also)
  562.       {
  563.         token = strtok(&zk[1], " ,\t\n");
  564.         if(token) strcpy(zk1, token);
  565.         else      zk1[0] = '\0';
  566.         while(token != NULL)
  567.         {
  568.           /* Ueberlesen des Textes vor ``/'' */
  569.           for(i=0; i<strlen(token); i++)
  570.           {
  571.             if(token[i]=='/') {
  572.               zk1[i]=NULL;
  573.               strcpy(zk2, &token[i+1]);
  574.               break; }
  575.           }
  576.  
  577.           /* Ist zk1 != Dateiname, dann wird ein Objekt ausserhalb
  578.              referenziert, sonst koennen wir den Dateinamen weglassen */
  579.           if(!strcmp(zk1, argv[1]))
  580.           {
  581.             fprintf(aus_daten, "@ref{%s}.\n", zk2);
  582.           }
  583.           else
  584.           {
  585.         /* Nun referenzieren in eine andere Datei:
  586.             zk2: Name der Referenz
  587.             zk1: Datei, in der die Referenz ist */
  588.         fprintf(aus_daten, "@xref{%s, , %s, %s, Autodoc-file %s}.\n",
  589.             zk2, zk2, zk1, zk1);
  590.           }
  591.  
  592.           token = strtok(NULL," ,\t\n");
  593.         }
  594.       }
  595.       else
  596.       {
  597.         if(convert_comment)
  598.         {
  599.           for(i=0; i<strlen(zk1); i++)
  600.             if(zk1[i] == '\\') zk1[i] = '/';
  601.  
  602.         }
  603.         fputs(&zk1[1], aus_daten);
  604.       }
  605.     }
  606.       /* Wir ignorieren das erste Zeichen links */
  607.     else
  608.     {
  609.       fprintf(aus_daten, "\n@code{%s}\n", zk1);
  610.       if(!see_also)  fputs("\n@example\n", aus_daten);
  611.       key_found = FALSE;
  612.     }
  613.       } /* keine Endkennung */
  614.     }
  615.     else /* Nicht im Autodoc-Modus */
  616.     { /* Autodoc-Modus startet mit einer Zeile, bei der das erste Zeichen
  617.      keine Rolle spielt, dann aber 6 '*' folgen, dann durch ein
  618.      Leerzeichen getrennt der Name der Funktion und dann durch ein
  619.      Leerzeichen getrennt beliebige Zeichen.
  620.          Es kann aber auch so sein, daß eine Kennung mitunterschieden
  621.          werden soll, wenn nur spezielle Teile extrahiert werden sollen,
  622.          z.B. die Docs in einer bestimmten Sprache. Dann wird nicht auf
  623.          6 '*' getestet, sondern auf "*ID***".
  624.          
  625.       */
  626.       if(! strncmp(&zk[1], generic_marker, MARKER_LENGTH) )
  627.       {
  628.         for(i=MARKER_LENGTH+1; i<strlen(zk); i++)
  629.         {
  630.           zk1[i-MARKER_LENGTH-1] = zk[i];
  631.           if(zk[i] == ' ')
  632.       {
  633.         zk1[i-MARKER_LENGTH-1]='\0';
  634.         break;
  635.       }
  636.         }
  637.         /* zk1: Name der Funktion, zk2 -> Beliebiger Rest */
  638.     if(!autodoc) /* Erster Eintrag? */
  639.     {
  640.       autodoc = TRUE;
  641.  
  642.           /* Now open the output files */
  643.           OpenOutputFiles(argv[2], &aus_menue, &aus_daten);
  644.       WriteTexinfo(
  645.         aus_menue, argv[2], author, project, version,
  646.         copyright, amiga_support);
  647.     }
  648.     autodoc_mode = TRUE;
  649.  
  650.         /* Ueberlese den Teil vor ``/'' */
  651.         token = strtok(zk1, "/");
  652.         token = strtok(NULL, " \n\t");
  653.  
  654.     /* Menue-Datei */
  655.     fprintf(aus_menue, "* %s::\n", token);
  656.     fprintf(aus_daten, "@node %s\n"
  657.                "@chapter %s\n"
  658.                "@findex %s\n\n",
  659.                 token, token, token);
  660.     
  661.       }
  662.  
  663.       /* Modus fuer die internen Funktionen */
  664.       if(! strncmp(&zk[1], internal_marker, MARKER_LENGTH) )
  665.       {
  666.         for(i=MARKER_LENGTH+1; i<strlen(zk); i++)
  667.         {
  668.           zk1[i-MARKER_LENGTH-1] = zk[i];
  669.           if(zk[i] == ' ')
  670.       {
  671.         zk1[i-MARKER_LENGTH-1]='\0';
  672.         break;
  673.       }
  674.         }
  675.  
  676.     /* Wir sollen auch die internen Docs extrahieren? */
  677.     if(extract_internal) 
  678.     {
  679.       if(!autodoc)    /* Erster Eintrag ueberhaupt? */
  680.       {
  681.         autodoc = TRUE;
  682.         /* Now open the output files */
  683.         OpenOutputFiles(argv[2], &aus_menue, &aus_daten);
  684.  
  685.         WriteTexinfo(
  686.         aus_menue, argv[2], author, project, version,
  687.         copyright, amiga_support);
  688.       }
  689.       autodoc_mode = TRUE;
  690.  
  691.       /* Ueberlese den Teil vor ``/'' */
  692.       token = strtok(zk1, "/");
  693.       token = strtok(NULL, " \n\t");
  694.  
  695.       /* Menue-Datei */
  696.       fprintf(aus_menue, "* %s:: Internal function\n", token);
  697.       fprintf(aus_daten, "@node %s\n"
  698.                "@chapter %s\n"
  699.                "@findex %s (Internal function)\n\n"
  700.                "@center ONLY FOR INTERNAL USE: @b{%s}\n\n",
  701.                 token, token, token, token);
  702.     }
  703.     else /* ueberlesen der INTERNEN Funktionsdokumentation */
  704.     {
  705.       BOOL haben_ende = FALSE;
  706.       while ( fgets(zk, sizeof(zk), ein) && !haben_ende )
  707.       {
  708.         zeile++;
  709.             if( !strncmp(zk, autodoc_end_marker, END_LENGTH) )
  710.          {
  711.         haben_ende = TRUE;
  712.         break;
  713.          }
  714.       } /* fgets() */
  715.       if(!haben_ende)
  716.       {
  717.         printf("Error: End of file occured during internal docs.\n");
  718.         exit(0);
  719.       }
  720.     } /* Ueberlesen der internen Dokumentation */
  721.       } /* BLOCK zum Lesen der internen Dokumentation */
  722.  
  723.       /* Ausfuellen der Slots (Fuer AUTHOR, etc): */
  724.       if(! strncmp(&zk[1], author_marker, MARKER_LENGTH) )
  725.       {
  726.         for(i=MARKER_LENGTH+1; i<strlen(zk); i++)
  727.         {
  728.           zk1[i-MARKER_LENGTH-1] = zk[i];
  729.           if(zk[i] == ' ')
  730.       {
  731.         zk1[i-MARKER_LENGTH-1]='\0';
  732.         break;
  733.       }
  734.         }
  735.         /* zk1: Name der Funktion */
  736.  
  737.     internal_ende = FALSE;
  738.  
  739.     if(autodoc) {
  740.       printf("Error Line %u: Header specified after autodocs.\n",
  741.         zeile);
  742.       exit(0); }
  743.  
  744.         if(internal) {
  745.       printf("Error Line %u: Second time header gets specified.\n", zeile);
  746.       exit(0); }
  747.       
  748.         /* Ueberlese den Teil vor ``/'' */
  749.         token = strtok(zk1, "/");
  750.         token = strtok(NULL, " \n\t");
  751.  
  752.         /* Now open the output files */
  753.         OpenOutputFiles(argv[2], &aus_menue, &aus_daten);
  754.  
  755.     /* Menue-Datei */
  756.     fprintf(aus_daten, "@node About_%s\n"
  757.                "@chapter About_%s\n"
  758.                "@findex About_%s\n\n",
  759.                 token, token, token);
  760.  
  761.         strcpy(zk2, token);
  762.     /* Nun solange lesen, bis wir die internal-Sachen abgearbeitet haben */
  763.     while ( fgets(zk, sizeof(zk), ein) && !internal_ende )
  764.     {
  765.       zeile++;
  766.           if( !strncmp(zk, autodoc_end_marker, END_LENGTH) )
  767.           {/* Endkennung erreicht */
  768.         for(i=0; i<sizeof(internal_keywords) / sizeof(char**); i++)
  769.         internal_key[i]=FALSE;
  770.  
  771.         internal_mode = FALSE;
  772.         internal = TRUE;
  773.         if(!see_also) fputs("@end example\n", aus_daten);
  774.         fputs("\n\n\n", aus_daten);
  775.         internal_ende = TRUE;
  776.           }
  777.           else /* Teste, auf Anfang fuer Internal-Modus */
  778.           {
  779.         /* Ueberlese erstes Zeichen und alle TABs, Leerzeichen */
  780.         strcpy(zk1, zk);
  781.         token = strtok(&zk[1], " \t\n");
  782.  
  783.         /* Schleifenvariable i dient spaeter als Indikator fuer
  784.            das Auffinden eines Schluesselwortes. Mit dem Setzen auf
  785.            einen Wert ausserhalb des Schluesselwort-Bereichs setzen
  786.            wir den Test fuers Finden auf FALSE */
  787.         i=sizeof(internal_keywords) / sizeof(char**);
  788.  
  789.             if(token)
  790.             {
  791.           for(i=0; i< sizeof(internal_keywords) / sizeof(char**); i++)
  792.           {
  793.             if(!strcmp(token, internal_keywords[i]))
  794.             {
  795.           last_key = i;
  796.               if(internal_key[i] == TRUE)
  797.               {
  798.             printf("Error Line %u: Keyword %s used twice.\n",
  799.               zeile, keywords[i]);
  800.             exit(0);
  801.               }
  802.               if(first_internal) fputs("@end example\n", aus_daten);
  803.               first_internal=TRUE;
  804.               internal_key[i] = TRUE;
  805.               strcpy(zk1, internal_keywords[i]);
  806.               break;
  807.             }
  808.           } /* Suche nach Keyword */
  809.         }
  810.  
  811.         /* Keyword? */
  812.         if(i!=sizeof(internal_keywords) / sizeof(char**))
  813.         {
  814.           fprintf(aus_daten, "\n@code{%s}\n", zk1);
  815.           fputs("\n@example\n", aus_daten);
  816.         }
  817.         else /* Wir haben kein Schluesselwort */
  818.         {
  819.           if(convert_comment)
  820.           {
  821.             for(i=0; i<strlen(zk1); i++)
  822.               if(zk1[i] == '\\') zk1[i] = '/';
  823.           }
  824.           strcpy(zk, zk1);
  825.           token = zk;
  826.           token = strpbrk(zk," \t");
  827.           switch(last_key)
  828.           {
  829.             case 3:    /* AUTHOR */
  830.           strncpy(author, token, 50);
  831.             break;
  832.  
  833.             case 0:    /* NAME */
  834.           strncpy(project, token, 50);
  835.             break;
  836.  
  837.             case 5:    /* VERSION */
  838.           strncpy(version, token, 50);
  839.             break;
  840.  
  841.             case 1:    /* COPYRIGHT*/
  842.           strncpy(copyright, token, 50);
  843.             break;
  844.           }
  845.           last_key = -1;
  846.           fputs(&zk1[1], aus_daten);
  847.         }
  848.           } /* keine Endkennung */
  849.     } /* fgets() */
  850.     /* Ende mit einlesen -> Kein Fehler, wenn internal == TRUE */
  851.     if(!internal) {
  852.       printf("Error: End of file occured during internal block.\n");
  853.       exit(0);
  854.     }
  855.  
  856.     WriteTexinfo(aus_menue, argv[2], author, project, version,
  857.             copyright, amiga_support);
  858.     fprintf(aus_menue, "* About_%s::\n", zk2);
  859.  
  860.         internal_mode = TRUE;
  861.         autodoc = TRUE;
  862.       } /* Internal-Kennung (AUTHOR, etc.) */
  863.  
  864.     }/* Nicht im Autodoc_modus */
  865.       
  866.   } /* fgets() */
  867.  
  868.   if(autodoc_mode) puts("Error: End of file during autodoc mode!");
  869.   else
  870.   {
  871.     /* Did we obtain something at all? */
  872.     if(autodoc)
  873.     {
  874.       /* Eliminate path specifiers like "/" and ":" */
  875.       for(i=strlen(argv[2])-1; i>=0; i--)
  876.         if(argv[2][i] == ':' || argv[2][i]=='/') break;
  877.       fprintf(aus_menue, "* Function Index::\n@end menu\n\n@include %s.data\n\n",
  878.             &argv[2][i+1]);
  879.       fprintf(aus_menue,  "@page\n@node Function Index\n\n"
  880.             "@unnumbered Function Index\n\n"
  881.             "@printindex fn\n@contents\n@bye\n");
  882.       fputs("\n\n", aus_daten);
  883.       printf("\"%s.menu\" is the main part.\n", argv[2]);
  884.     }
  885.     else
  886.       puts("-> No autodocs found, so no files were created.");
  887.   }
  888.  
  889. } /* main() */
  890.  
  891.  
  892. /* Eine Extrawurst f"ur den DICE Compiler, der den Start von der WB
  893.    eigenwillig handhabt.  */
  894. #ifdef _DCC
  895. void wbmain(void)
  896. {
  897.   main();
  898. }
  899. #endif
  900.  
  901.  
  902.  
  903.  
  904.  
  905.